using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Threading;

namespace Rhizome.Internal
{

	public static class DispatcherExtension
	{
		/// <summary>
		/// Gets the current thread dispatcher
		/// todo: optimize
		/// </summary>
		public static Dispatcher CurrentDispatcher
		{
			[DebuggerStepThrough]
			get { return new MyDependencyObject().Dispatcher; }
		}
#if SILVERLIGHT || WINDOWS_PHONE

		/// <summary>
		/// 	SL & WP7 extension methos for synchronously action execution
		/// </summary>
		/// <param name = "dispatcher"></param>
		/// <param name = "action"></param>
		public static void Invoke(this Dispatcher dispatcher, Action action)
		{
			if (dispatcher.CheckAccess())
			{
				action();
				return;
			}

			var monitor = new object();
			lock (monitor)
			{
				dispatcher.BeginInvoke(
					() =>
						{
							action();
							lock (monitor) Monitor.Pulse(monitor);
						});
				Monitor.Wait(monitor);
			}
		}

		public static T Invoke<T>(this Dispatcher dispatcher, Func<T> func)
		{
			var val = default(T);
			dispatcher.Invoke(() => { val = func(); });
			return val;
		}

#endif

		#region Nested type: MyDependencyObject

		private sealed class MyDependencyObject : DependencyObject
		{
		}

		#endregion
	}
}